package models; import java.io.*; import java.lang.reflect.Type; import java.util.*; import java.util.stream.Collectors; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.KeyDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.google.gson.typeadapters.RuntimeTypeAdapterFactory; import flexjson.JSONDeserializer; import flexjson.JSONSerializer; public class Dictionary implements DictionaryProc, Observer, Serializable { private static Dictionary instance; private HashMap<DictionaryEntry, ArrayList<DictionaryEntry>> entries = new HashMap<>(); private Dictionary() { } public static Dictionary getInstance() { if (instance == null) instance = new Dictionary(); return instance; } public void add(DictionaryEntry entry, boolean populate) throws IllegalOperationException { if (!populate) assert WellFormed(); assert entry != null; assert !(entries.containsKey(entry)); int size = entries.size(); if (entries.containsKey(entry)) throw new IllegalOperationException("Entry already there"); entries.put(entry, new ArrayList<DictionaryEntry>()); serialize(); assert entries.containsKey(entry); assert size + 1 == entries.size(); if (!populate) assert WellFormed(); } public void removeKey(DictionaryEntry entry, boolean populate) throws IllegalOperationException { if (!populate) assert WellFormed(); assert entry != null; assert entries.containsKey(entry); int size = entries.size(); int i, size2; if (!(entries.containsKey(entry))) throw new IllegalOperationException("Entry not there"); entries.remove(entry); for (DictionaryEntry de : entries.keySet()) { for (i = 0; i < entries.get(de).size(); i++) { DictionaryEntry de2 = entries.get(de).get(i); if (de2 instanceof Phrase) { if (((Phrase) de2).getContent().contains(entry)) entries.get(de).remove(de2); } else { entries.get(de).remove(entry); } } } serialize(); assert !(entries.containsKey(entry)); assert size - 1 == entries.size(); if (!populate) assert WellFormed(); } public void removeDefinition(DictionaryEntry entry, DictionaryEntry definition, boolean populate) throws IllegalOperationException { if (!populate) assert WellFormed(); assert entry != null; assert definition != null; assert entries.containsKey(entry); assert entries.get(entry).contains(definition); int size = entries.get(entry).size(); if (!(entries.containsKey(entry))) throw new IllegalOperationException("Entry not there"); if (!(entries.get(entry).contains(definition))) throw new IllegalOperationException("Entry not there"); entries.get(entry).remove(definition); serialize(); assert entries.containsKey(entry); assert !(entries.get(entry).contains(definition)); assert entries.get(entry).size() + 1 == size; if (!populate) assert WellFormed(); } public void define(DictionaryEntry entry, DictionaryEntry definition, boolean populate) throws IllegalOperationException { if (!populate) assert WellFormed(); assert entry != null; assert definition != null; assert entries.containsKey(entry); assert entries.get(entry) != null; int size = entries.get(entry).size(); if (!(entries.containsKey(entry))) throw new IllegalOperationException("Entry not there"); entries.get(entry).add(definition); if (!(WellFormed()) && !(populate)) { entries.get(entry).remove(definition); throw new IllegalOperationException("Not a consistent defintion"); } serialize(); assert !(entries.get(entry).isEmpty()); assert size + 1 == entries.get(entry).size(); if (!populate) { assert WellFormed(); } } public HashMap<DictionaryEntry, ArrayList<DictionaryEntry>> search(String pattern) { int i; HashMap<DictionaryEntry, ArrayList<DictionaryEntry>> result = new HashMap<>(); String pattern2 = ""; boolean begin = true; for (i = 0; i < pattern.length(); i++) { if (pattern.charAt(i) == '*') pattern2 += ".*"; else if (pattern.charAt(i) == '?') pattern2 += ".{1}"; else pattern2 += pattern.charAt(i); } for (DictionaryEntry de : entries.keySet()) if (((Word) de).getContent().matches(pattern2)) result.put(de, entries.get(de)); return result; } public boolean checkIfPreposition(DictionaryEntry preposition) { for (DictionaryEntry de : entries.keySet()) for (DictionaryEntry de2 : entries.get(de)) if (de2 instanceof Phrase) if (((Phrase) de2).getContent().contains(preposition)) return true; return false; } public void serialize() { ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(); class DictionaryEntrySerializer extends JsonSerializer<DictionaryEntry> { @Override public void serialize(DictionaryEntry arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException, JsonProcessingException { arg1.writeFieldName(String.valueOf(arg0.toString())); } } SimpleModule module = new SimpleModule(); module.addKeySerializer(DictionaryEntry.class, new DictionaryEntrySerializer()); mapper.registerModule(module); try { String json = mapper.writeValueAsString(this); FileWriter wr = new FileWriter("Dictionary.json"); wr.write(json); wr.close(); } catch (JsonProcessingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void deserialize() { ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(); class ExampleClassKeyDeserializer extends KeyDeserializer { @Override public Object deserializeKey(final String key, final DeserializationContext ctxt) throws IOException, JsonProcessingException { return new Word(key, false); } } class ExampleJacksonModule extends SimpleModule { public ExampleJacksonModule() { addKeyDeserializer(DictionaryEntry.class, new ExampleClassKeyDeserializer()); } } mapper.registerModule(new ExampleJacksonModule()); try { BufferedReader br = new BufferedReader(new FileReader("Dictionary.json")); instance = mapper.readValue(br, Dictionary.class); br.close(); } catch (IOException e) { e.printStackTrace(); } } public boolean WellFormed() { for (DictionaryEntry de : entries.keySet()) for (DictionaryEntry de2 : entries.get(de)) if (de2 instanceof Phrase) { for (DictionaryEntry de3 : ((Phrase) de2).getContent()) if (!(((Word) de3).isPreposition())) if (!(entries.containsKey(de3))) return false; } else if (!(((Word) de2).isPreposition())) if (!(entries.containsKey(de2))) return false; return true; } @Override public void update(Observable o, Object arg) { String newContent = (String) arg; Word old = (Word) o; ArrayList<DictionaryEntry> definition = entries.get(old); entries.remove(old); for (DictionaryEntry de : entries.keySet()) for (DictionaryEntry de2 : entries.get(de)) if (de2 instanceof Phrase) for (DictionaryEntry de3 : ((Phrase) de2).getContent()) { if (de3.equals(old)) ((Word) de3).setContent(newContent); else if (de2.equals(old)) ((Word) de2).setContent(newContent); } else if (de2.equals(old)) ((Word) de2).setContent(newContent); entries.put(new Word(newContent, false), definition); serialize(); } public HashMap<DictionaryEntry, ArrayList<DictionaryEntry>> getEntries() { return entries; } public void setEntries(HashMap<DictionaryEntry, ArrayList<DictionaryEntry>> entries) { this.entries = entries; } public String toString() { return entries.entrySet().stream().map(entry -> entry.getKey() + " = " + entry.getValue()) .collect(Collectors.joining("; ", "[", "]")); } }